/*
--------------------------------------------------------------------------------
				Ak-Lib. 
			 Project       	: Ak-Lib
			 Group         	: Ak-Lib R&D Team
			 Author        	: Ocean.Wang
			 Create Date 	: 05-01-2010
--------------------------------------------------------------------------------
Code Name 	:  A.K 	~v~
Description	:  Yet Another Cross-Platform Lib.
Cautions    	:
--------------------------------------------------------------------------------
Change History:
Version		: 0.1
Building 		: 05/01/10
10-05.01 first draft, build, debug and test.
--------------------------------------------------------------------------------
*/

#ifndef _INC_AK_MC_
#define	_INC_AK_MC_

#include "ak_types.h"
#include "ak_lru.h"
#include "ak_task.h"
#include "ak_jobq.h"
#include "ak_htbl.h"
#include "ak_zip.h"
#include "ak_socket.h"

#ifdef __cplusplus
extern "C" {
#endif

/* 
===========================================================
Ak-Lib Cache Protocol:

1. Hash Algorithm & Parallel Perf

2. LRU & Lazy-GC.

3. Multi-Port.

4. Schedule.
*/

typedef struct _t_mc_item {
	_t_sysLruCi 		ci;
	#if 0
	unsigned int 		rLen;		/* Real Length, for Compress/De PiggyBack Check */
	unsigned int 		dLen;		
	#endif
	unsigned int 		length;		
    unsigned char  		pseudo[0];
} _t_mc_item;

extern	_t_mc_item *	McItem_Get(_t_sysLruCt * pBucket, void * pKey, void * pData, 	size_t lData);
extern	_t_mc_item * 	McItem_Set(_t_sysLruCt * pBucket, void * pKey, void * pData, size_t lData, time_t expire);
extern	int 			McItem_Del(_t_sysLruCt * pBucket, void * pKey);


extern	_t_mc_item *McItem_Alloc(_t_sysMHeap * pHeap, size_t  size);
extern	int 		McItem_Free(_t_sysLruCt * pBucket, _t_mc_item * pItem);
extern	int 		McItem_FreeQ(_t_sysMHeap * pHeap, _t_blist * pQueue);
extern	int 		McHeap_GC(_t_sysMHeap * pHeap);


/* Returns Internal Alk */
extern	void * 			Mc_HeapInit(_t_sysMHeap ** ppHeap, size_t memLimit);

/* Data Encode/Decode, Compress/Decompress Process */
static 	__inline int 	_Mc_DataEnc(unsigned char * inBuf, unsigned char * outBuf, int inLen)
{
	return (int)_Qlz_Compress(inBuf, outBuf, inLen);
}
static 	__inline int 	_Mc_DataDec(unsigned char * inBuf, unsigned char * outBuf, int outLen)
{
	return (int)_Qlz_Decompress(inBuf, outBuf, outLen);
}


/* =====================================================================
**	 Mc Message Definition:
*/
/* Command */
#define _MC_CMD_GET 		0X00
#define _MC_CMD_SET 		0X01

#define _MC_CMD_DEL 		0X04

#define _MC_CMD_INC 		0X05
#define _MC_CMD_DEC 		0X06


/* ErrorNo */
#define _MC_ERR_OK 			0X00

#define _MC_ERR_NFOUND 		0X01		/* Key Not Found 		*/
#define _MC_ERR_EXIST 		0X02		/* Key Already Exist 	*/
#define _MC_ERR_EXCEED		0X03 		/* Too large to OP 		*/
#define _MC_ERR_PARAM 		0X04		/* Invalid Parameter 	*/

#define _MC_ERR_CMD 		0X81
#define _MC_ERR_OOM 		0X82

/* Data Control */
#define _MC_DC_RAW 			0X00		/* Raw Bytes 		*/

#define _MC_MSG_MAXSZ 		0X80000
#define _MC_MSG_ZIPSZ 		0X100

#define _MC_SAP_INTER 		0XCCCC

typedef struct _t_mc_data{
	unsigned int		rLen;			/* Real Length */
	unsigned int		dLen;			/* Data Length, maybe Zipped */
	unsigned long long	key;			/* Key */
	unsigned char		pseudo[0];
}_t_mc_data;

extern	int 	McItem_DataSet(_t_mc_item * pItem, _t_mc_data * pData, size_t lData);
extern	int 	McItem_DataGet(_t_mc_item * pItem, _t_mc_data * pData, size_t lData);

extern 	int 	McItem_KeyBind(_t_mc_item * pItem);
extern	int 	McItem_KeyComp(_t_rbnode * node1, _t_rbnode * node2);

typedef struct _t_mc_message{
	_t_sysMsgElem		elem;		/* User Custom the PiggyBack for Routing */	

	/* Operation & Status Code */
	int  				code;			
	/* Set the Expiration of the Key-Value
	**	= 0	: never expiration. 
	**	> 0	: the data could be LRU after expiration.  
	*/	
	unsigned int 		expire;			
	_t_mc_data 			data;
}_t_mc_message;


typedef struct _t_mc_trans{
	/* IP Addr & Port */
	unsigned short 		port;
	unsigned short 		reserv;
	unsigned int 		ipAddr;
	/* Link Handle */
	void * 				pHandle;
}_t_mc_trans;

extern	int 	McTrans_Tx(_t_mc_trans * pTrans, _t_sgbuf *	sgBuf, int sgCnt);


/* =====================================================================
**	 Mc Server Definition:
*/
extern	void * 		McSc_Init(size_t mLimit, unsigned short port);
extern	int 		McSc_Parse(void * pArg, int lArg, _t_mc_message * pMsg, int msgLen, _t_mc_trans * pTrans);
extern	int 		McSc_Dump(void * pArg);


/* =====================================================================
**	 Mc Client Definition:
*/
extern	int 	McCc_Get(void * pMcCc, unsigned long long  key, int timeout, _t_cbentry	* pCbEntry);
extern	int 	McCc_GetEx(void * pMcCc, unsigned long long key, int timeout, unsigned char * pBuf, int * lBuf);
extern	int 	McCc_Del(void * 	pMcCc, unsigned long long key);
extern	int 	McCc_Set(void *	pMcCc, unsigned long long key, int expire, unsigned char * pBuf, int lBuf);
extern	void * 	McCc_Init(_t_cbentry * pCombine);


#ifdef __cplusplus
}
#endif

#endif

